<template>
  <div class="login-image">
    <a-row style="min-height: 100%">
      <a-col :offset="12" :span="12">
        <a-card hoverable style="width: 350px" class="login-card-body">
          <template #title>
            <login-outlined style="color: dodgerblue; margin-right: 5px;" v-if="cardTitle === '欢迎登录'"/>
            <trademark-outlined style="color: dodgerblue; margin-right: 5px;" v-if="cardTitle === '注册'"/>
            <edit-outlined style="color: dodgerblue; margin-right: 5px;" v-if="cardTitle === '忘记密码'"/>
            <span style="color: dodgerblue;">{{ cardTitle }}</span>
          </template>
          <!--登录-->
          <a-form
              ref="loginRef"
              :model="loginForm"
              :rules="loginRules"
              v-if="cardTitle === '欢迎登录'"
              name="normal_login"
              layout="vertical"
          >
            <a-form-item
                label="用户名"
                name="username"
            >
              <a-input v-model:value.trim="loginForm.username" placeholder="请输入用户名">
                <template #prefix>
                  <UserOutlined/>
                </template>
              </a-input>
            </a-form-item>

            <a-form-item
                label="密码"
                name="password"
            >
              <a-input-password v-model:value.trim="loginForm.password" placeholder="请输入密码">
                <template #prefix>
                  <LockOutlined/>
                </template>
              </a-input-password>
            </a-form-item>
            <a-form-item class="login-form-button">
              <a-button :disabled="disabled" :loading="loading" @click="loginRes" type="primary" html-type="submit">
                登录
              </a-button>
            </a-form-item>
          </a-form>
          <!--注册-->
          <a-form
              ref="registerRef"
              :model="registerForm"
              :rules="registerRules"
              v-if="cardTitle === '注册'"
              name="normal_login"
              layout="vertical"
          >
            <a-form-item
                label="用户名"
                name="username"
            >
              <a-input v-model:value.trim="registerForm.username" placeholder="用户名以汉字、英文和数字组成">
                <template #prefix>
                  <UserOutlined/>
                </template>
              </a-input>
            </a-form-item>

            <a-form-item
                label="昵称"
                name="nickname"
            >
              <a-input v-model:value.trim="registerForm.nickname" placeholder="默认为用户名">
                <template #prefix>
                  <UserOutlined/>
                </template>
              </a-input>
            </a-form-item>

            <a-form-item
                label="密码"
                name="password"
            >
              <a-input-password v-model:value.trim="registerForm.password" placeholder="请输入密码">
                <template #prefix>
                  <LockOutlined/>
                </template>
              </a-input-password>
            </a-form-item>

            <a-form-item
                label="确认密码"
                name="checkPassword"
            >
              <a-input-password v-model:value.trim="registerForm.checkPassword" placeholder="请输入确认密码">
                <template #prefix>
                  <LockOutlined/>
                </template>
              </a-input-password>
            </a-form-item>

            <a-form-item
                name="problem1"
                label="验证问题"
                has-feedback
            >
              <a-select v-model:value="registerForm.problem1" placeholder="请选择验证问题">
                <a-select-option v-for="p in problemList" :key="p.problemid" :value="p.problemid">{{
                    p.problem
                  }}
                </a-select-option>
              </a-select>
            </a-form-item>

            <a-form-item
                label="回答"
                name="answer1"
            >
              <a-input v-model:value.trim="registerForm.answer1" placeholder="请输入回答">
                <template #prefix>
                  <font-size-outlined/>
                </template>
              </a-input>
            </a-form-item>

            <a-form-item class="login-form-button">
              <a-button :disabled="registerDisabled" :loading="loading" @click="registerRes" type="primary" html-type="submit">
                注册
              </a-button>
            </a-form-item>
          </a-form>
          <!--忘记密码-->
          <a-form
              ref="forgetRef"
              :model="forgetForm"
              :rules="forgetRules"
              v-if="cardTitle === '忘记密码'"
              name="normal_login"
              layout="vertical"
          >
            <a-form-item
                label="用户名"
                name="username"
            >
              <a-input v-model:value.trim="forgetForm.username" placeholder="请输入用户名">
                <template #prefix>
                  <UserOutlined/>
                </template>
              </a-input>
            </a-form-item>

            <a-form-item
                label="密码"
                name="password"
            >
              <a-input-password v-model:value.trim="forgetForm.password" placeholder="请输入密码">
                <template #prefix>
                  <LockOutlined/>
                </template>
              </a-input-password>
            </a-form-item>

            <a-form-item
                label="确认密码"
                name="checkPassword"
            >
              <a-input-password v-model:value.trim="forgetForm.checkPassword" placeholder="请输入确认密码">
                <template #prefix>
                  <LockOutlined/>
                </template>
              </a-input-password>
            </a-form-item>

            <a-form-item
                name="problem1"
                label="验证问题"
                has-feedback
            >
              <a-select v-model:value="forgetForm.problem1" placeholder="请选择注册时的验证问题">
                <a-select-option v-for="p in problemList" :key="p.problemid" :value="p.problemid">{{
                    p.problem
                  }}
                </a-select-option>
              </a-select>
            </a-form-item>

            <a-form-item
                label="回答"
                name="answer1"
            >
              <a-input v-model:value.trim="forgetForm.answer1" placeholder="请输入回答">
                <template #prefix>
                  <font-size-outlined/>
                </template>
              </a-input>
            </a-form-item>

            <a-form-item class="login-form-button">
              <a-button :disabled="forgetDisabled" :loading="loading" @click="forgetRes" type="primary" html-type="submit">
                提交
              </a-button>
            </a-form-item>
          </a-form>

          <template #actions>
            <a-tooltip placement="bottom" color="dodgerblue">
              <template #title>
                <span>登录</span>
              </template>
              <login-outlined @click="changeTool('欢迎登录')"/>
            </a-tooltip>
            <a-tooltip placement="bottom" color="dodgerblue">
              <template #title>
                <span>注册</span>
              </template>
              <trademark-outlined @click="changeTool('注册')"/>
            </a-tooltip>
            <a-tooltip placement="bottom" color="dodgerblue">
              <template #title>
                <span>忘记密码</span>
              </template>
              <edit-outlined @click="changeTool('忘记密码')"/>
            </a-tooltip>
          </template>
        </a-card>
      </a-col>
    </a-row>
  </div>
</template>

<script>
import {useRouter} from "vue-router";
import {ref, reactive, getCurrentInstance, computed, onBeforeMount, toRefs} from "vue";
import {apiRequest, queryProblem, register, login, forgetPassword} from "@/service/service";
import utils from "@/utils/utils";

export default {
  name: "LoginView",
  setup() {
    /** 下方菜单栏 **/
    const cardTitle = ref('欢迎登录');
    const changeTool = (val) => {
      cardTitle.value = val
    }
    const {proxy} = getCurrentInstance()
    const router = useRouter()
    const loading = ref(false)

    /** 公共参数校验 **/
    let usernameValid = async (_rule, value) => {
      if (!value) {
        return Promise.reject("请输入用户名！")
      } else if (utils.hasSpecialChar(value)) {
        return Promise.reject("用户名不合规！")
      } else if (value.length > 20 || value.length < 4) {
        return Promise.reject("用户名长度范围4-20个字符！")
      }
      return Promise.resolve()
    }
    let passwordValid = async (_rule, value) => {
      if (!value || value.length < 8 || value.length > 20) {
        return Promise.reject("密码长度范围8-20个字符！")
      }
      return Promise.resolve()
    }
    let answer1Valid = async (_rule, value) => {
      if (value.length > 50) {
        return Promise.reject("字数不能超过50字符！")
      }
      return Promise.resolve()
    }

    /** 登录数据 **/
    const loginRef = ref()
    const loginForm = reactive({
      username: '',
      password: ''
    })
    const disabled = computed(() => {
      return !(loginForm.username && loginForm.password);
    });
    const loginRules = {
      username: [{
        required: true,
        trigger: 'change',
        validator: usernameValid
      }],
      password: [{
        required: true,
        trigger: 'change',
        validator: passwordValid
      }]
    }

    function loginRes() {
      loginRef.value.validateFields().then(() => {
        loading.value = true
        apiRequest(login(loginForm), response => {
          loading.value = false
          proxy.$Message.success("登录成功")
          loginRef.value.resetFields()
          sessionStorage.setItem('token', response.data.token)
          localStorage.setItem('userData', JSON.stringify(response.data))
          router.push({
            name: 'index'
          })
        }, () => loading.value = false)
      }).catch(() => {
        proxy.$Notice.error("数据不合规！")
      })
    }

    /** 注册数据 **/
    const registerRef = ref()
    const registerForm = reactive({
      username: '',
      nickname: '',
      password: '',
      checkPassword: '',
      problem1: null,
      answer1: ''
    })
    const registerDisabled = computed(() => {
      return !(registerForm.username && registerForm.password
          && registerForm.checkPassword
          && registerForm.password === registerForm.checkPassword
          && registerForm.problem1
          && registerForm.answer1
      )
    })
    let nicknameValid = async (_rule, value) => {
      if (value.length > 20) {
        return Promise.reject("昵称长度不能超过20个字符！")
      }
      return Promise.resolve()
    }
    let checkPasswordValid = async (_rule) => {
      if (registerForm.password !== registerForm.checkPassword) {
        return Promise.reject("密码与确认密码不一致！")
      }
      return Promise.resolve()
    }
    const registerRules = ({
      username: [{
        required: true,
        trigger: 'change',
        validator: usernameValid
      }],
      nickname: [{
        required: false,
        trigger: 'change',
        validator: nicknameValid
      }],
      password: [{
        required: true,
        trigger: 'change',
        validator: passwordValid
      }],
      checkPassword: [{
        required: true,
        trigger: 'change',
        validator: checkPasswordValid
      }],
      problem1: [{
        required: true,
        trigger: 'change',
        message: '请选择问题！'
      }],
      answer1: [{
        required: true,
        trigger: 'change',
        validator: answer1Valid
      }]
    })

    function registerRes() {
      registerRef.value.validateFields().then(() => {
        loading.value = true
        apiRequest(register(registerForm), () => {
          loading.value = false
          proxy.$Message.success("注册成功")
          registerRef.value.resetFields()
        }, () => loading.value = false)
      }).catch(() => {
        proxy.$Notice.error("数据不合规！")
      })
    }

    /** 忘记密码 **/
    const forgetRef = ref()
    const state = reactive({
      problemList: []
    })
    onBeforeMount(() => {
      apiRequest(queryProblem(), response => {
        state.problemList = response.data
      })
    })
    const forgetForm = reactive({
      username: '',
      password: '',
      checkPassword: '',
      problem1: null,
      answer1: ''
    })
    let forgetCheckPasswordValid = async (_rule) => {
      if (forgetForm.password !== forgetForm.checkPassword) {
        return Promise.reject("密码与确认密码不一致！")
      }
      return Promise.resolve()
    }
    const forgetRules = ({
      username: [{
        required: true,
        trigger: 'change',
        validator: usernameValid
      }],
      password: [{
        required: true,
        trigger: 'change',
        validator: passwordValid
      }],
      checkPassword: [{
        required: true,
        trigger: 'change',
        validator: forgetCheckPasswordValid
      }],
      problem1: [{
        required: true,
        trigger: 'change',
        message: '请选择问题！'
      }],
      answer1: [{
        required: true,
        trigger: 'change',
        validator: answer1Valid
      }]
    })
    const forgetDisabled = computed(() => {
      return !(forgetForm.username && forgetForm.password
          && forgetForm.checkPassword
          && forgetForm.password === forgetForm.checkPassword
          && forgetForm.problem1
          && forgetForm.answer1
      )
    })

    function forgetRes() {
      forgetRef.value.validateFields().then(() => {
        loading.value = true
        apiRequest(forgetPassword(forgetForm), () => {
          loading.value = false
          proxy.$Message.success("密码重置成功！")
          forgetRef.value.resetFields()
        }, () => loading.value = false)
      }).catch(() => {
        proxy.$Notice.error("数据不合规！")
      })
    }

    return {
      cardTitle,
      loading,
      loginRef,
      loginForm,
      disabled,
      loginRules,
      loginRes,
      registerRef,
      registerForm,
      registerDisabled,
      registerRules,
      registerRes,
      forgetRef,
      forgetForm,
      forgetDisabled,
      forgetRules,
      forgetRes,
      ...toRefs(state),
      changeTool,
    }
  }
}
</script>

<style>
.login-card-body {
  position: absolute;
  top: 50%;
  /*transform: translateY(-60%);*/
  transform: translate(40%, -50%);
}

.login-card-body .ant-card-body {
  padding: 10px 20px 0;
}

.login-form-button {
  margin: 0
}

.login-form-button button {
  margin-left: 110px;
}

.login-image {
  width: 100%;
  height: 100%;
  background-image: url("../assets/login.png");
  background-size: cover;
  position: relative;
}

</style>
